package game;

import java.util.ArrayList;

import parser.ChessContentHandlerConstants;

import command.Command;
/**
 * This class hold all the moves that are currently made by the chess game. It has built in 
 * functions like redo and undo.
 * @author Caleb Chan and Max Joyce
 *
 */
public class MoveExecutionList extends ArrayList<Command> {

	private static final long serialVersionUID = 1L;
	private int currentItemsPlace;
	private boolean hasUndone;
	
	public MoveExecutionList(){
		super();
		currentItemsPlace = -1;
		hasUndone = false;
	} 
	/**
	 * This method will add an object of type command to the array list. If there has been 
	 * any undos it will delete all moves above the undo.
	 * @param o A command object to be added
	 */
	public boolean add(Command o){
		checkForUndos();
		boolean isAdded = super.add(o);
		if(isAdded){
			currentItemsPlace++;
			hasUndone = false;
		}
		return isAdded;
	}
	/**
	 * This method will undo the most recently added move from this list 
	 * @return Returns true if the undo was successful
	 */
	public synchronized boolean undo(){
		if(currentItemsPlace >= 0){
			super.get(currentItemsPlace).undo();
			currentItemsPlace--;
			hasUndone = true;
			return true;
		}
		return false;
	}
	/**
	 * This method will redo moves only if there is an undo called and no add methods calls after
	 * @return Returns true if the redo was successful
	 */
	public synchronized boolean redo(){
		if(currentItemsPlace < super.size() - 1){
			currentItemsPlace++;
			super.get(currentItemsPlace).execute();	
			return true;
		}
		return false;
	}
	/**
	 * This method will check if there has been any undos done. If there has been
	 * it will delete all items above the undo.
	 */
	private void checkForUndos(){
		if(hasUndone){
			super.removeRange(currentItemsPlace + 1, super.size());
		}
	}
	/**
	 * This method will get the last command done. It will also take into account
	 * any undos done
	 * @return Returns a the last command object
	 */
	public Command getLastCommand(){
		
		//This shouldn't work if only one move has been made
		if (currentItemsPlace==-1){
			return null;
		}
		return super.get(currentItemsPlace); //Return the last one
		
	}
	/**
	 * This method will return a string representation of the move list
	 * @return Returns a string of the list
	 */
	public String toString(){
		String s ="";
		for(int i = 0; i < currentItemsPlace + 1; i ++){
			s += this.get(i).toString() + "\n";
		}
		return s;
	}
	/**
	 * This method will return a string representation of the move list for exporting
	 * @return Returns a string of the list for exporting
	 */
	public String exportList(){
		String s ="";
		for(Command c : this){
			s+= c.exportCode() + "\n";
		}
		return s;
	}
	/** 
	 * This method will convert the move list into an xml string.
	 * @return Returns a xml string representation of the llst
	 */
	public String XMLSaveList(){
		String s = "";
		for(int i = 0; i < this.size(); i++){
			s += "<" + ChessContentHandlerConstants.ELEMENT_COMMMAND + ">\n";
			s += "\t" + this.get(i).xmlCode().replaceAll("\n", "\n\t");
			s += "\n";
			s += "</" + ChessContentHandlerConstants.ELEMENT_COMMMAND + ">\n";
		}
		return s;
	}
	public int getCurrentSize(){
		return currentItemsPlace;
	}
}
